﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Kaspersky.Test.RecursiveLinkLogger;
using log4net;

namespace Kaspersky.Test.ConsoleApp
{
    class Program
    {
        static ILog _log;

        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("No url specified!");
                return;
            }

            // taking log4net configuration from app.config
            log4net.Config.XmlConfigurator.Configure();
            _log = LogManager.GetLogger("main");

            Console.WriteLine("Press any key to start scanning {0}...", args[0]);
            Console.ReadKey();

            var sw = new Stopwatch();
            sw.Start();

            TestAsyncLinkLogger(args[0]);

            sw.Stop();

            Console.WriteLine("Finished! It took " + sw.ElapsedMilliseconds + " ms");

#if DEBUG
            // this is needed to be able to see all the unhandled task exceptions

            Console.WriteLine("Press any key...");
            Console.ReadKey();

            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            Console.WriteLine("Press one more any key...");
            Console.ReadKey();
#endif
        }

        static void TestAsyncLinkLogger(string url)
        {
            var linker = new AsyncLinkLogger<StateMachineLinkExtractorWithHttpPrefix>();

            int linkCount = 0;

            // tell the LinkLogger what to do when a link found
            linker.LinkFoundEvent += link =>
            {
                Interlocked.Increment(ref linkCount);
                Console.WriteLine(linkCount + " " + link);
                _log.Info(link);
            };

            linker.ExceptioEvent += ex =>
            {
                Console.WriteLine("!Exception: " + ex.Message);
                _log.Error(ex.Message);
            };

            // go
            var logLinksTask = linker.LogLinks(url);

            Console.WriteLine("Press any key to cancel");
            Console.ReadKey();

            // now cancelling the process and waiting it to finish
            linker.Cancel();
            logLinksTask.Wait();
        }

        static void TestLinkLogger(string url)
        {
            var linker = new LinkLogger<StateMachineLinkExtractorWithHttpPrefix>();

            // tell the LinkLogger what to do when a link found
            linker.LinkFoundEvent += link =>
            {
                Console.WriteLine(link);
                _log.Info(link);
            };

            // go
            linker.LogLinks(url);

            // collecting exceptions
            foreach (var err in linker.Errors)
            {
                Console.WriteLine(err.Message);
                _log.Error(err);
            }
        }
    }
}
